package com.ryhx.rcb;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.sql.Connection;
import java.sql.DatabaseMetaData;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashSet;
import java.util.Iterator;

import com.ryhx.main.DaoAndServiceProducer;
import com.ryhx.main.FileDirProducer;
import com.ryhx.util.ConfigUtil;
import com.ryhx.util.ConnectionUtil;
import com.ryhx.util.MysqlUtil;
/**
 * 辽阳 RCB项目的entity和mapper代码生成
 */
public class LyRCBCodeProducer {
	static FileWriter fw;
	static StringBuilder mapperContentSB = null;//mapper文件生成sb
	static StringBuilder entityContentSB = null;//entity文件生成sb
	static String INDENTATION_1 = "    ";// 缩进1个单位 即4个空格
	static String INDENTATION_2 = "        ";// 缩进2个单位 即8个空格
	static String INDENTATION_3 = "            ";// 缩进3个单位 即12个空格
	static String INDENTATION_4 = "                ";// 缩进4个单位 即16个空格
	static String NEWLINESTR = "\n";//一个换行标识
	//mapper.xml头部
	public static String mapperXmlHeader = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"+ NEWLINESTR + "<!DOCTYPE mapper PUBLIC \"-//mybatis.org//DTD Mapper 3.0//EN\" \"http://mybatis.org/dtd/mybatis-3-mapper.dtd\">" + NEWLINESTR + NEWLINESTR;
	//mapper.xml注释
	public static String mapperXmlComment = "<!-- 这里可以写Mapper文件的注释  " + new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()) +" -->" + NEWLINESTR;
	public static String primaryKeyColumnName = null;//主键列名
	public static String primaryKeyInEntityName = null;//主键列名在实体中的名称
	public static String[] columnArray = null;// 列名数组
	public static String[] entityPropertyNameArray = null;//实体类的属性名称数组
	public static String[] columnDefaultValueArray = null;//列默认值数组
	public static String[] columnTypeArray = null;//列类型数组
	public static String[] entityPropertyTypeArray = null;//实体类的属性类型数组
	public static int[] columnDatasizeArray = null;//列的大小数组
	public static int[] columnDigitsArray = null;//列的精度数组
	public static int[] columnNullableArray = null;//列是否为空 数组  0 不能为空 1 可以为空
	public static String[] columnAutoIncrementArray = null;//列是否自增 数组  是否自增 YES自增 NO非自增
	public static String[] columnRemarksArray = null;//列的注释 数组
	
	public static void main(String[] args) {
		try {
			FileDirProducer.createDir();
			createEntityAndMapperFile();
			createFacadeContent();
			createFacadeImplContent();
			createBiz();
			createDao();
			createDaoImpl();
			createControllerFile();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	
	/**
	 * 生成 controller 文件
	 */
	public static void createControllerFile() {

		//System.out.println("controller文件：暂时不生成");
		try {
			// 按行读取DaoTemplate的内容
			String controllerTemplateFileSourceString = DaoAndServiceProducer.readFileByLines("template/TemplateController.txt");
			controllerTemplateFileSourceString = controllerTemplateFileSourceString.replace("package ","package " + ConfigUtil.controllerPackagePath); // 替换第一行的包名
			controllerTemplateFileSourceString = controllerTemplateFileSourceString.replaceAll("simpleModelNameLower",ConfigUtil.simpleModelNameLower);// 替换所有小写的实体命名
			controllerTemplateFileSourceString = controllerTemplateFileSourceString.replaceAll("firstCharLowerSimpleModelName", ConfigUtil.firstCharLowerSimpleModelName);// 替换掉所有首字母小写的实体命名
			controllerTemplateFileSourceString = controllerTemplateFileSourceString.replaceAll("SimpleModelName", ConfigUtil.simpleModelName);// 替换掉所有类名称
			controllerTemplateFileSourceString = controllerTemplateFileSourceString.replaceAll("entityName",ConfigUtil.entityName);// 替换掉所有提示信息变量
			writeControllerContentToControllerFile(controllerTemplateFileSourceString);
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			try {
				fw.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}
	/**
	 * 写入 controller 内容到 文件中
	 * @param controllerTemplateFileSourceString 
	 * @throws Exception 
	 */
	private static void writeControllerContentToControllerFile(String controllerTemplateFileSourceString) throws Exception {
		File controllerFile = new File("source/" + ConfigUtil.simpleModelNameLower + "/controller/" + ConfigUtil.simpleModelName + "Controller.java");
		if (!controllerFile.exists()) {
			System.out.println("---初始化实体简称：" + ConfigUtil.simpleModelName + "的controller文件:" + controllerFile.getName() + "创建");
			controllerFile.createNewFile();
			System.out.println("---初始化实体简称：" + ConfigUtil.simpleModelName + "的controller文件:" + controllerFile.getName() + "创建完成");
		}
		System.out.println("---初始化实体简称：" + ConfigUtil.simpleModelName + "的Controller文件:" + controllerFile.getName() + "写入");
		fw = new FileWriter(controllerFile);
		fw.write(controllerTemplateFileSourceString);
		System.out.println("---初始化实体简称：" + ConfigUtil.simpleModelName + "的Controller文件:" + controllerFile.getName() + "写入完成");
	}
	
	/** @Description 创建facade文件内容 <pre>
	 * 
	 * @return  返回值类型: <pre>  
	 * @author 作者: yaojinshan <pre>
	 * @date 2018年9月6日 下午12:24:17 <pre> 
	 * @throws 异常: <pre>
	 */
	private static void createFacadeContent() {
		System.out.println("---生产facade文件---实体全路径名称：" + ConfigUtil.modelPackagePath + ConfigUtil.simpleModelName + ",实体简称：" + ConfigUtil.simpleModelName + "---start");
		try {
			// 按行读取DaoTemplate的内容
			String daoTemplateFileSourceString = readFileByLines("template/FacadeContent.txt");
			daoTemplateFileSourceString = daoTemplateFileSourceString.replaceAll("Template", ConfigUtil.simpleModelName);// 替换掉所有类名称
			daoTemplateFileSourceString = daoTemplateFileSourceString.replaceAll("template",
					ConfigUtil.firstCharLowerSimpleModelName);// 替换掉所有实体实例名称
			File daoFile = new File("source/" + ConfigUtil.simpleModelNameLower + "/facade/" + "FacadeContent.java");
			if (!daoFile.exists()) {
				System.out.println("---初始化实体简称：" + ConfigUtil.simpleModelName + "的facade文件:" + daoFile.getName() + "创建");
				daoFile.createNewFile();
				System.out.println("---初始化实体简称：" + ConfigUtil.simpleModelName + "的facade文件:" + daoFile.getName() + "创建完成");
			}
			System.out.println("---初始化实体简称：" + ConfigUtil.simpleModelName + "的facade文件:" + daoFile.getName() + "写入");
			fw = new FileWriter(daoFile);
			fw.write(daoTemplateFileSourceString);
			System.out.println("---初始化实体简称：" + ConfigUtil.simpleModelName + "的facade文件:" + daoFile.getName() + "写入完成");
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			try {
				fw.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		System.out.println("---生产facade文件---实体全路径名称：" + ConfigUtil.modelPackagePath + ConfigUtil.simpleModelName + ",实体简称：" + ConfigUtil.simpleModelName + "---end");
		System.out.println();
	}
	/** @Description 创建facadeImpl文件内容 <pre>
	 * 
	 * @return  返回值类型: <pre>  
	 * @author 作者: yaojinshan <pre>
	 * @date 2018年9月6日 下午12:24:17 <pre> 
	 * @throws 异常: <pre>
	 */
	private static void createFacadeImplContent() {
		System.out.println("---生产facadeImpl文件---实体全路径名称：" + ConfigUtil.modelPackagePath + ConfigUtil.simpleModelName + ",实体简称：" + ConfigUtil.simpleModelName + "---start");
		try {
			// 按行读取DaoTemplate的内容
			String daoTemplateFileSourceString = readFileByLines("template/FacadeContentImpl.txt");
			daoTemplateFileSourceString = daoTemplateFileSourceString.replaceAll("Template", ConfigUtil.simpleModelName);// 替换掉所有类名称
			daoTemplateFileSourceString = daoTemplateFileSourceString.replaceAll("template",
					ConfigUtil.firstCharLowerSimpleModelName);// 替换掉所有实体实例名称
			File daoFile = new File("source/" + ConfigUtil.simpleModelNameLower + "/facade/impl/" + "FacadeContentImpl.java");
			if (!daoFile.exists()) {
				System.out.println("---初始化实体简称：" + ConfigUtil.simpleModelName + "的facadeImpl文件:" + daoFile.getName() + "创建");
				daoFile.createNewFile();
				System.out.println("---初始化实体简称：" + ConfigUtil.simpleModelName + "的facadeImpl文件:" + daoFile.getName() + "创建完成");
			}
			System.out.println("---初始化实体简称：" + ConfigUtil.simpleModelName + "的facadeImpl文件:" + daoFile.getName() + "写入");
			fw = new FileWriter(daoFile);
			fw.write(daoTemplateFileSourceString);
			System.out.println("---初始化实体简称：" + ConfigUtil.simpleModelName + "的facadeImpl文件:" + daoFile.getName() + "写入完成");
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			try {
				fw.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		System.out.println("---生产facadeImpl文件---实体全路径名称：" + ConfigUtil.modelPackagePath + ConfigUtil.simpleModelName + ",实体简称：" + ConfigUtil.simpleModelName + "---end");
		System.out.println();
	}
	/** @Description 创建createBiz文件内容 <pre>
	 * 
	 * @return  返回值类型: <pre>  
	 * @author 作者: yaojinshan <pre>
	 * @date 2018年9月6日 下午12:24:17 <pre> 
	 * @throws 异常: <pre>
	 */
	private static void createBiz() {
		System.out.println("---生产biz文件---实体全路径名称：" + ConfigUtil.modelPackagePath + ConfigUtil.simpleModelName + ",实体简称：" + ConfigUtil.simpleModelName + "---start");
		try {
			// 按行读取DaoTemplate的内容
			String daoTemplateFileSourceString = readFileByLines("template/TemplateBiz.txt");
			daoTemplateFileSourceString = daoTemplateFileSourceString.replaceAll("Template", ConfigUtil.simpleModelName);// 替换掉所有类名称
			daoTemplateFileSourceString = daoTemplateFileSourceString.replaceAll("template",
					ConfigUtil.firstCharLowerSimpleModelName);// 替换掉所有实体实例名称
			File daoFile = new File("source/" + ConfigUtil.simpleModelNameLower + "/biz/" + ConfigUtil.simpleModelName + "Biz.java");
			if (!daoFile.exists()) {
				System.out.println("---初始化实体简称：" + ConfigUtil.simpleModelName + "的biz文件:" + daoFile.getName() + "创建");
				daoFile.createNewFile();
				System.out.println("---初始化实体简称：" + ConfigUtil.simpleModelName + "的biz文件:" + daoFile.getName() + "创建完成");
			}
			System.out.println("---初始化实体简称：" + ConfigUtil.simpleModelName + "的biz文件:" + daoFile.getName() + "写入");
			fw = new FileWriter(daoFile);
			fw.write(daoTemplateFileSourceString);
			System.out.println("---初始化实体简称：" + ConfigUtil.simpleModelName + "的biz文件:" + daoFile.getName() + "写入完成");
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			try {
				fw.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		System.out.println("---生产facadeImpl文件---实体全路径名称：" + ConfigUtil.modelPackagePath + ConfigUtil.simpleModelName + ",实体简称：" + ConfigUtil.simpleModelName + "---end");
		System.out.println();
	}
	/** @Description 创建createDao文件内容 <pre>
	 * 
	 * @return  返回值类型: <pre>  
	 * @author 作者: yaojinshan <pre>
	 * @date 2018年9月6日 下午12:24:17 <pre> 
	 * @throws 异常: <pre>
	 */
	private static void createDao() {
		System.out.println("---生产Dao文件---实体全路径名称：" + ConfigUtil.modelPackagePath + ConfigUtil.simpleModelName + ",实体简称：" + ConfigUtil.simpleModelName + "---start");
		try {
			// 按行读取DaoTemplate的内容
			String daoTemplateFileSourceString = readFileByLines("template/Dao_Null_Content.txt");
			daoTemplateFileSourceString = daoTemplateFileSourceString.replaceAll("Template", ConfigUtil.simpleModelName);// 替换掉所有类名称
			daoTemplateFileSourceString = daoTemplateFileSourceString.replaceAll("template",
					ConfigUtil.firstCharLowerSimpleModelName);// 替换掉所有实体实例名称
			File daoFile = new File("source/" + ConfigUtil.simpleModelNameLower + "/dao/" + ConfigUtil.simpleModelName + "Dao.java");
			if (!daoFile.exists()) {
				System.out.println("---初始化实体简称：" + ConfigUtil.simpleModelName + "的Dao文件:" + daoFile.getName() + "创建");
				daoFile.createNewFile();
				System.out.println("---初始化实体简称：" + ConfigUtil.simpleModelName + "的Dao文件:" + daoFile.getName() + "创建完成");
			}
			System.out.println("---初始化实体简称：" + ConfigUtil.simpleModelName + "的Dao文件:" + daoFile.getName() + "写入");
			fw = new FileWriter(daoFile);
			fw.write(daoTemplateFileSourceString);
			System.out.println("---初始化实体简称：" + ConfigUtil.simpleModelName + "的Dao文件:" + daoFile.getName() + "写入完成");
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			try {
				fw.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		System.out.println("---生产facadeImpl文件---实体全路径名称：" + ConfigUtil.modelPackagePath + ConfigUtil.simpleModelName + ",实体简称：" + ConfigUtil.simpleModelName + "---end");
		System.out.println();
	}
	/** @Description 创建createDaoImpl文件内容 <pre>
	 * 
	 * @return  返回值类型: <pre>  
	 * @author 作者: yaojinshan <pre>
	 * @date 2018年9月6日 下午12:24:17 <pre> 
	 * @throws 异常: <pre>
	 */
	private static void createDaoImpl() {
		System.out.println("---生产DaoImpl文件---实体全路径名称：" + ConfigUtil.modelPackagePath + ConfigUtil.simpleModelName + ",实体简称：" + ConfigUtil.simpleModelName + "---start");
		try {
			// 按行读取DaoTemplate的内容
			String daoTemplateFileSourceString = readFileByLines("template/DaoImpl_Null_Content.txt");
			daoTemplateFileSourceString = daoTemplateFileSourceString.replaceAll("Template", ConfigUtil.simpleModelName);// 替换掉所有类名称
			daoTemplateFileSourceString = daoTemplateFileSourceString.replaceAll("template",
					ConfigUtil.firstCharLowerSimpleModelName);// 替换掉所有实体实例名称
			File daoFile = new File("source/" + ConfigUtil.simpleModelNameLower + "/dao/impl/" + ConfigUtil.simpleModelName + "DaoImpl.java");
			if (!daoFile.exists()) {
				System.out.println("---初始化实体简称：" + ConfigUtil.simpleModelName + "的DaoImpl文件:" + daoFile.getName() + "创建");
				daoFile.createNewFile();
				System.out.println("---初始化实体简称：" + ConfigUtil.simpleModelName + "的DaoImpl文件:" + daoFile.getName() + "创建完成");
			}
			System.out.println("---初始化实体简称：" + ConfigUtil.simpleModelName + "的DaoImpl文件:" + daoFile.getName() + "写入");
			fw = new FileWriter(daoFile);
			fw.write(daoTemplateFileSourceString);
			System.out.println("---初始化实体简称：" + ConfigUtil.simpleModelName + "的DaoImpl文件:" + daoFile.getName() + "写入完成");
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			try {
				fw.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		System.out.println("---生产facadeImpl文件---实体全路径名称：" + ConfigUtil.modelPackagePath + ConfigUtil.simpleModelName + ",实体简称：" + ConfigUtil.simpleModelName + "---end");
		System.out.println();
	}
	/**
	 * 按行读取文件
	 * @param fileName
	 * @return
	 */
	public static String readFileByLines(String fileName) {
		File file = new File(fileName);
		BufferedReader reader = null;
		try {
			System.out.println("以行为单位读取文件内容，一次读一整行：");
			reader = new BufferedReader(new FileReader(file));
			String tempString = null;
			String returnStr = "";
			//int line = 1;
			// 一次读入一行，直到读入null为文件结束
			while ((tempString = reader.readLine()) != null) {
				// 显示行号
				//System.out.println("line " + line + ": " + tempString);
				returnStr += tempString + "\n";
				//line++;
			}
			reader.close();
			return returnStr;
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			if (reader != null) {
				try {
					reader.close();
				} catch (IOException e1) {
				}
			}
		}
		return "";
	}

	/**
	 * 创建 Entity和Mapper文件
	 * @throws Exception 
	 */
 	public static void createEntityAndMapperFile() throws Exception{
		Connection connection = ConnectionUtil.getConnection();
		try {
			//获取数据库元属性
			DatabaseMetaData dbMeta = connection.getMetaData();
			//获取数据库名称
			String database_name = connection.getCatalog();
			//获取表的主键名称
			primaryKeyColumnName = getPrimaryKeyColumnName(dbMeta,database_name);
			primaryKeyInEntityName = getColumnInEntityName(primaryKeyColumnName);
			//ResultSet tableResultSet = null;
			//多表查询 第一个参数为数据库名称  第二个参数  可以模糊匹配表名  第三个参数可以是具体的表名 第四个参数 固定格式 new String[]{"TABLE"} 查询类型是表的 应该也可以查视图 触发器等类型 
			//tableResultSet = dbMeta.getTables(database_name,null,null,new String[]{"TABLE"});  
			//单表查询
			//tableResultSet = dbMeta.getTables(database_name,null,ConfigUtil.database_table,new String[]{"TABLE"});  
			//String tableName = "";//表名
			//while(tableResultSet.next()){  
				//tableName = tableResultSet.getString("TABLE_NAME");  
				//System.out.println(tableName);
			//}
			//提取表内的字段的名字和类型 
			ResultSet colRet = dbMeta.getColumns(null,null, ConfigUtil.database_table,"%");
			//获取列的其他属性
			ResultSetMetaData rsMeta = getResultSetMetaData(connection);
			//初始化静态数据：将数据库表字段属性 全部初始化到静态变量里边
			initStaticData(colRet,rsMeta);
			 //创建mapper文件
			createMapperFile();
			//创建实体类文件
			createEntityFile();
			ConnectionUtil.releaseConn();
		} catch (SQLException e) {
			e.printStackTrace();
		}
	}
 	/**
 	 * 获取 resultSetMetaData 为了表的列数量 以及表的各个列的属性  以及 列属性对应的entity实体属性
 	 * @param connection
 	 * @return
 	 * @throws Exception
 	 */
	private static ResultSetMetaData getResultSetMetaData(Connection connection) throws Exception {
		String sql = "select * from " + ConfigUtil.database_table + " limit 0,10";
		PreparedStatement stmt;
		stmt = connection.prepareStatement(sql);
		ResultSet rs = stmt.executeQuery(sql);
		return rs.getMetaData();
	}
	/**
 	 * 获取列名 在java实体中的名称
 	 * @param columnName
 	 * @return
 	 */
 	private static String getColumnInEntityName(String columnName) {
 		columnName = columnName.toLowerCase();//必须先转换为小写 否则 数据库建表时命名不规范 容易生成的实体属性出现异常
 		String[] tempArray = columnName.split("_");
		StringBuilder sb = new StringBuilder();
		for(String str : tempArray){
			sb.append(str.substring(0, 1).toUpperCase()).append(str.substring(1));
		}
		String str = sb.toString();
		return str.substring(0, 1).toLowerCase() + str.substring(1);
	}
	/**
 	 * 获取表的主键名称
 	 * @param connection 
 	 * @return
 	 * @throws Exception 
 	 */
 	private static String getPrimaryKeyColumnName(DatabaseMetaData dbMeta,String database_name) throws Exception {
 		//获取数据库指定表的主键
		ResultSet primaryKeyResultSet = dbMeta.getPrimaryKeys(database_name,null,ConfigUtil.database_table);
		while(primaryKeyResultSet.next()){
			primaryKeyColumnName = primaryKeyResultSet.getString("COLUMN_NAME");
			System.out.println(ConfigUtil.database_table + "表的主键为：" + primaryKeyColumnName);
			return primaryKeyColumnName;
		}
		if("".equals(primaryKeyColumnName) || primaryKeyColumnName == null ){
			System.out.println(ConfigUtil.database_table + "表必须设置主键，当前没有主键");
			System.exit(0);
		}
		return null;  
	}
 	/**
 	 * 创建Mapper文件
 	 * @param connection
 	 * @throws Exception
 	 */
 	public static void createMapperFile() throws Exception{
 		mapperContentSB = new StringBuilder();
		mapperContentSB.append(mapperXmlHeader);//添加Mapper头部
		mapperContentSB.append(mapperXmlComment);//Mapper注释
		//添加 mapper行数据
		addNamespaceRowContent();
		//添加createTable的sql
		addCreateTableSql();
		addBaseResultMapSql();
		//添加 列名集合 sql语句
		addSelectSql();
		//添加 where 条件sql语句
		addWhereSql();
		//添加get单个对象sql语句
		addGetByIdSql();
		addDeleteByIdSql();
		//addDeleteSql();
		addListBySql();
		addListPageSql();
		//添加insert一个对象sql语句
		addInsertSql();
		//添加update对象sql语句
		addUpdateSql();
		//添加mapper结束标签
		mapperContentSB.append("</mapper>");
		//将mapper内容 写入mapper文件
		writeMapperContentToMapperFile();
 	}
 	/**
	 * 添加listBy Sql语句
	 */
	public static void addListBySql() {
		StringBuilder  listBySqlSB = new StringBuilder();
		listBySqlSB.append(INDENTATION_1 +  "<!-- list by sql 语句-->" + NEWLINESTR);
		listBySqlSB.append(INDENTATION_1 + "<select id=\"listBy\" resultMap=\"BaseResultMap\" parameterType=\"java.util.Map\">" + NEWLINESTR);
		listBySqlSB.append(INDENTATION_2 + "select <include refid=\"Base_Column_List\"/> from " + ConfigUtil.database_table + " " + ConfigUtil.firstCharLowerSimpleModelName + " <where>  <include refid=\"whereSql\"/> </where>" + NEWLINESTR);
		listBySqlSB.append(INDENTATION_1 + "</select>" + NEWLINESTR);
		mapperContentSB.append(listBySqlSB.toString());
	}
	/**
	 * 添加listPage Sql语句
	 */
	public static void addListPageSql() {
		StringBuilder  listPageSqlSB = new StringBuilder();
		listPageSqlSB.append(INDENTATION_1 +  "<!-- list page sql 语句-->" + NEWLINESTR);
		listPageSqlSB.append(INDENTATION_1 + "<select id=\"listPage\" resultMap=\"BaseResultMap\" parameterType=\"java.util.Map\">" + NEWLINESTR);
		listPageSqlSB.append(INDENTATION_2 + "select <include refid=\"Base_Column_List\"/> from " + ConfigUtil.database_table + " " + ConfigUtil.firstCharLowerSimpleModelName + " <where>  <include refid=\"whereSql\"/> </where>" + NEWLINESTR);
		listPageSqlSB.append(INDENTATION_1 + "</select>" + NEWLINESTR);
		mapperContentSB.append(listPageSqlSB.toString());
	}
	/**
	 * 添加insert一个对象sql语句
	 */
	public static void addInsertSql() {
		StringBuilder  insertSqlSB = new StringBuilder();//插入sql语句
		insertSqlSB.append(INDENTATION_1 +  "<!-- insert sql 语句-->" + NEWLINESTR);
		insertSqlSB.append(INDENTATION_1 + "<insert id=\"insert\" parameterType=\"" +  ConfigUtil.modelPackagePath + "." + ConfigUtil.simpleModelName + "\">" + NEWLINESTR);
		insertSqlSB.append(INDENTATION_2 + "<selectKey resultType=\"Long\" order=\"AFTER\" keyProperty=\"" + primaryKeyInEntityName + "\">" + NEWLINESTR);
		insertSqlSB.append(INDENTATION_3 + "<choose><when test=\"" + primaryKeyInEntityName + "==null\">SELECT LAST_INSERT_ID() AS " + primaryKeyInEntityName + "</when><otherwise>SELECT #{" + primaryKeyInEntityName + ",jdbcType=" + convertJdbcType(columnTypeArray[0]) + "} as " + primaryKeyInEntityName + "</otherwise></choose>" + NEWLINESTR);
		insertSqlSB.append(INDENTATION_2 + "</selectKey>" + NEWLINESTR);
		insertSqlSB.append(INDENTATION_2 + "insert into "+ ConfigUtil.database_table + " (" + NEWLINESTR);
		for(int i = 0 ; i < columnArray.length;i++){
			if(columnArray[i].equals(primaryKeyColumnName)){
				insertSqlSB.append(INDENTATION_3 + "<if test=\""+ primaryKeyInEntityName + "!=null\">`" + primaryKeyColumnName + "`,</if>"+ NEWLINESTR + INDENTATION_3);
			}else if(i > 0 && i < columnArray.length - 1){
				insertSqlSB.append("`"+columnArray[i]+"`,");
			}else if(i == columnArray.length - 1){
				insertSqlSB.append("`"+columnArray[i]+"`)" + NEWLINESTR);
			}
		}
		insertSqlSB.append(INDENTATION_2 + "values(" + NEWLINESTR);
		for(int i = 0 ; i < columnArray.length;i++){
			if(columnArray[i].equals(primaryKeyColumnName)){
				insertSqlSB.append(INDENTATION_3 + "<if test=\""+ primaryKeyInEntityName + "!=null\">#{" + primaryKeyInEntityName + ",jdbcType=" + convertJdbcType(columnTypeArray[i]) + "},</if>"+ NEWLINESTR);
			}else if(i > 0 && i < columnArray.length - 1){
				if(MysqlUtil.TYPE_NAME_DATETIME.equals(columnTypeArray[i].toLowerCase()) || MysqlUtil.TYPE_NAME_DATE.equals(columnTypeArray[i].toLowerCase())){
					insertSqlSB.append(INDENTATION_3 +"<choose><when test=\"" + entityPropertyNameArray[i] + "==null\">" + columnDefaultValueArray[i] + "</when><otherwise>#{" + entityPropertyNameArray[i] + ",jdbcType=TIMESTAMP}</otherwise></choose>," + NEWLINESTR);
				}else{
					insertSqlSB.append(INDENTATION_3 +"<choose><when test=\"" + entityPropertyNameArray[i] + "==null\">" + columnDefaultValueArray[i] + "</when><otherwise>#{" + entityPropertyNameArray[i] + ",jdbcType=" + convertJdbcType(columnTypeArray[i]) + "}</otherwise></choose>," + NEWLINESTR);
				}
			}else if(i == columnArray.length - 1){
				if(MysqlUtil.TYPE_NAME_DATETIME.equals(columnTypeArray[i].toLowerCase()) || MysqlUtil.TYPE_NAME_DATE.equals(columnTypeArray[i].toLowerCase())){
					insertSqlSB.append(INDENTATION_3 +"<choose><when test=\"" + entityPropertyNameArray[i] + "==null\">" + columnDefaultValueArray[i] + "</when><otherwise>#{" + entityPropertyNameArray[i] + ",jdbcType=TIMESTAMP}</otherwise></choose>" + NEWLINESTR);
				}else{
					insertSqlSB.append(INDENTATION_3 +"<choose><when test=\"" + entityPropertyNameArray[i] + "==null\">" + columnDefaultValueArray[i] + "</when><otherwise>#{" + entityPropertyNameArray[i] + ",jdbcType=" + convertJdbcType(columnTypeArray[i]) + "}</otherwise></choose>" + NEWLINESTR);
				}
			}
		}
		insertSqlSB.append(INDENTATION_2 + ")" + NEWLINESTR);
		insertSqlSB.append(INDENTATION_1 + "</insert>" + NEWLINESTR);
		mapperContentSB.append(insertSqlSB.toString());
	}
	/**
	 * 添加updateSql 语句
	 */
	public static void addUpdateSql(){
		StringBuilder  updateSqlSB = new StringBuilder();
		updateSqlSB.append(INDENTATION_1 +  "<!-- update sql 语句-->" + NEWLINESTR);
		updateSqlSB.append(INDENTATION_1 + "<update id=\"update\" parameterType=\"" +  ConfigUtil.modelPackagePath + "." + ConfigUtil.simpleModelName + "\">" + NEWLINESTR);
		updateSqlSB.append(INDENTATION_2 + "update "+ ConfigUtil.database_table +" "+ ConfigUtil.firstCharLowerSimpleModelName + NEWLINESTR);
		updateSqlSB.append(INDENTATION_2 + "<set>" + NEWLINESTR);
		for(int i = 1 ; i < columnArray.length;i++){
			updateSqlSB.append(INDENTATION_3 +"<if test=\"" + entityPropertyNameArray[i] + "!=null\">" + ConfigUtil.firstCharLowerSimpleModelName + "." + columnArray[i] + " = #{" + entityPropertyNameArray[i] + ",jdbcType=" + convertJdbcType(columnTypeArray[i]) + "},</if>" + NEWLINESTR);
		}
		updateSqlSB.append(INDENTATION_2 + "</set>" + NEWLINESTR);
		updateSqlSB.append(INDENTATION_2 + "where " + ConfigUtil.firstCharLowerSimpleModelName + "." + primaryKeyColumnName + "=#{" + primaryKeyInEntityName + ",jdbcType=" + convertJdbcType(columnTypeArray[0]) + "}" + NEWLINESTR);
		updateSqlSB.append(INDENTATION_1 + "</update>" + NEWLINESTR);
		mapperContentSB.append(updateSqlSB.toString());
	}
 	/**
	 * 添加deleteById sql语句
	 */
	public static void addDeleteByIdSql() {
		StringBuilder  deleteByIdSqlSB = new StringBuilder();
		deleteByIdSqlSB.append(INDENTATION_1 +  "<!-- delete by id sql 语句-->" + NEWLINESTR);
		deleteByIdSqlSB.append(INDENTATION_1 + "<delete id=\"deleteById\" parameterType=\"" + entityPropertyTypeArray[0] + "\">" + NEWLINESTR);
		deleteByIdSqlSB.append(INDENTATION_2 + "delete from " + ConfigUtil.database_table + 
				" where " + primaryKeyColumnName + " = #{" + primaryKeyInEntityName + ",jdbcType=" + convertJdbcType(columnTypeArray[0]) + "}" + NEWLINESTR);
		deleteByIdSqlSB.append(INDENTATION_1 + "</delete>" + NEWLINESTR);
		mapperContentSB.append(deleteByIdSqlSB.toString());
	}
 	/**
	 * 添加 where 条件sql
	 */
	public static void addWhereSql() throws Exception {
		StringBuilder  whereSqlSB = new StringBuilder();
		whereSqlSB.append(INDENTATION_1 +  "<!-- where条件集合 -->" + NEWLINESTR);;
		whereSqlSB.append(INDENTATION_1 +  "<sql id=\"whereSql\">" + NEWLINESTR);
		for(int i = 0 ; i < columnArray.length; i ++){
			whereSqlSB.append(INDENTATION_2 + "<if test=\"" + entityPropertyNameArray[i] + "!=null\"> and " + ConfigUtil.firstCharLowerSimpleModelName + "." + columnArray[i] + " = #{" + entityPropertyNameArray[i] + ",jdbcType=" + convertJdbcType(columnTypeArray[i]) + "}</if>" + NEWLINESTR);
		}
		whereSqlSB.append(INDENTATION_2 + "<if test=\"whereSql!=null\"> ${whereSql}</if>" + NEWLINESTR);
		whereSqlSB.append(INDENTATION_1 + "</sql>" + NEWLINESTR);
		mapperContentSB.append(whereSqlSB.toString());
	}
 	/**
	 * 添加getById Sql语句
	 */
	public static void addGetByIdSql() {
		StringBuilder  getByIdSqlSB = new StringBuilder();
		getByIdSqlSB.append(INDENTATION_1 +  "<!-- get by id sql 语句 -->" + NEWLINESTR);
		getByIdSqlSB.append(INDENTATION_1 + "<select id=\"getById\" resultMap=\"BaseResultMap\" parameterType=\"" + entityPropertyTypeArray[0] + "\">" + NEWLINESTR);
		getByIdSqlSB.append(INDENTATION_2 + "select <include refid=\"Base_Column_List\"/> from " + ConfigUtil.database_table +" " + ConfigUtil.firstCharLowerSimpleModelName + 
				" where " + ConfigUtil.firstCharLowerSimpleModelName + "." + primaryKeyColumnName + " = #{" + primaryKeyInEntityName + ",jdbcType=" + convertJdbcType(columnTypeArray[0])  + "}" + NEWLINESTR);
		getByIdSqlSB.append(INDENTATION_1 + "</select>" + NEWLINESTR);
		mapperContentSB.append(getByIdSqlSB.toString());
	}
 	/**
	 * 添加createTable的sql
	 * @throws Exception 
	 */
	public static void addCreateTableSql() throws Exception {
		StringBuilder  createSqlSB = new StringBuilder();//创建表sql语句
		createSqlSB.append(INDENTATION_1 +  "<!-- 建表语句 sql -->" + NEWLINESTR);;
		createSqlSB.append(INDENTATION_1 + "<sql id=\"createTable\">" + NEWLINESTR).append(INDENTATION_2  + "DROP TABLE `"+ ConfigUtil.database_table +"`;" + NEWLINESTR);
		createSqlSB.append(INDENTATION_2 + "CREATE TABLE `"+ ConfigUtil.database_table +"`(" + NEWLINESTR);
		if(null != primaryKeyColumnName){
			createSqlSB.append(INDENTATION_3 + "PRIMARY KEY (`"+primaryKeyColumnName +"`) ," + NEWLINESTR);
		}
		for(int i = 0;i < columnArray.length; i++ ){
			createSqlSB.append(INDENTATION_3 + "`" + columnArray[i]+ "` " + MysqlUtil.getColumnTypeStr(columnTypeArray[i],columnDatasizeArray[i],columnDigitsArray[i]));
			createSqlSB.append(MysqlUtil.getNullableStr(columnNullableArray[i]));
			createSqlSB.append(MysqlUtil.getAutoIncrement(columnAutoIncrementArray[i]));
			createSqlSB.append(MysqlUtil.getColumnRemarks(columnRemarksArray[i]));
			createSqlSB.append(MysqlUtil.getColumnDefaultStr(columnTypeArray[i],columnDefaultValueArray[i]));
			if(i ==  columnArray.length - 1){
				createSqlSB.append(NEWLINESTR);
			}else{
				createSqlSB.append("," + NEWLINESTR);
			}
		}
		createSqlSB.append(INDENTATION_2 + ")" + NEWLINESTR);
		createSqlSB.append(INDENTATION_1 + "</sql>" + NEWLINESTR);
		mapperContentSB.append(createSqlSB.toString());
	}

	public static void addBaseResultMapSql() throws Exception {
		StringBuilder  baseResultMapSqlSB = new StringBuilder();//创建表sql语句
		baseResultMapSqlSB.append(INDENTATION_1 +  "<!-- BaseResultMap 结果集 -->" + NEWLINESTR);
		baseResultMapSqlSB.append(INDENTATION_1 + "<resultMap id=\"BaseResultMap\" type=\""+ConfigUtil.modelPackagePath + "." + ConfigUtil.simpleModelName+"\">" + NEWLINESTR);
		baseResultMapSqlSB.append(INDENTATION_2 + "<id column=\""+primaryKeyColumnName+"\" property=\""+primaryKeyInEntityName+"\" jdbcType=\""+columnTypeArray[0]+"\"/>" + NEWLINESTR);
		for(int i = 1;i < columnArray.length; i++ ){
			baseResultMapSqlSB.append(INDENTATION_2 + "<result column=\""+columnArray[i]+"\" property=\""+entityPropertyNameArray[i]+"\" jdbcType=\""+ convertJdbcType(columnTypeArray[i]) +"\"/>" + NEWLINESTR);
		}
		baseResultMapSqlSB.append(INDENTATION_1 + "</resultMap>" + NEWLINESTR);
		mapperContentSB.append(baseResultMapSqlSB.toString());
	}
	/**
	 * 添加 列名集合 sql语句
	 * @throws Exception 
	 */
	public static void addSelectSql() throws Exception {
		//格式 <sql id="Base_Column_List"></sql>
		StringBuilder  selectSqlSB = new StringBuilder();//列名集合 sql语句
		selectSqlSB.append(INDENTATION_1 +  "<!-- 表字段集合 -->" + NEWLINESTR);
		selectSqlSB.append(INDENTATION_1 +  "<sql id=\"Base_Column_List\">" + NEWLINESTR);
		for(int i = 0 ; i < columnArray.length; i ++){
			if(i == columnArray.length -1){
				selectSqlSB.append(INDENTATION_2 + ConfigUtil.firstCharLowerSimpleModelName + "." + columnArray[i] + " "  + entityPropertyNameArray[i] + NEWLINESTR);
			}else{
				selectSqlSB.append(INDENTATION_2 + ConfigUtil.firstCharLowerSimpleModelName + "." + columnArray[i] + " "  + entityPropertyNameArray[i] +  "," + NEWLINESTR);
			}
		}
		selectSqlSB.append(INDENTATION_1 + "</sql>" + NEWLINESTR);
		mapperContentSB.append(selectSqlSB.toString());
	}
	/**
	 * @Description 转化jdbc类型 <pre>
	 * @param columnType
	 * @return
	 * @return  返回值类型: <pre>  
	 * @author 作者: yaojinshan <pre>
	 * @date 2018年7月9日 下午12:47:17 <pre> 
	 * @throws 异常: <pre>
	 */
	private static String convertJdbcType(String columnType) {
		if("date".equalsIgnoreCase(columnType)){
			return "TIME";
		}else if("datetime".equalsIgnoreCase(columnType)){
			return "TIMESTAMP";
		}else if("int".equalsIgnoreCase(columnType)){
			return "INTEGER";
		}else if("text".equalsIgnoreCase(columnType)){
			return "LONGVARCHAR";
		}else{
			return columnType;
		}
	}
 	/**
	 * 将mapper内容 写入mapper文件
	 */
	public static void writeMapperContentToMapperFile(){
		FileWriter fw = null;
		try {
			String filePath = "source/" + ConfigUtil.simpleModelNameLower + "/mapper/" + ConfigUtil.simpleModelName  + "Mapper.xml";
			File mapperFile = new File(filePath);
			if(!mapperFile.exists()){
				mapperFile.createNewFile();
			}
			fw = new FileWriter(mapperFile);
			fw.write(mapperContentSB.toString());
			System.out.println(ConfigUtil.simpleModelName + "Mapper.xml写入成功！文件存放路径为：" + filePath);
		} catch (IOException e) {
			System.out.println(ConfigUtil.simpleModelName + "Mapper.xml写入失败！");
		}finally {
			try {
				fw.close();
			} catch (IOException e) {
				System.out.println("写入mapper文件的写入流关闭是失败！");
			}
		}
	}
 	/**
 	 * 添加 namespace 行头内容
 	 * 需要在程序最后添加上mapper结束标签  &lt;/mapper&gt;
 	 */
	public static void addNamespaceRowContent() {
		//格式：com.study.web.dao.sysuser.impl.SysUserDaoImpl
		mapperContentSB.append("<mapper namespace=\"" + ConfigUtil.daoPackagePath + ".impl."
				+ ConfigUtil.simpleModelName+"DaoImpl\">" + NEWLINESTR);
	}
 	/**
 	 * 创建实体类文件
 	 */
 	public static void createEntityFile(){
 		entityContentSB = new StringBuilder();
 		//添加package
 		entityContentSB.append("package " + ConfigUtil.modelPackagePath + ";" + NEWLINESTR + NEWLINESTR);
 		//添加import
 		HashSet<String> hset = new HashSet<>();
 		for(int i = 0 ; i < entityPropertyTypeArray.length; i++ ){
 			if(entityPropertyTypeArray[i].indexOf("java.lang") >=0){
 				continue;
 			}else{
 				hset.add(entityPropertyTypeArray[i]);
 			}
 		}
 		Iterator<String> it = hset.iterator();
 		while(it.hasNext()){
 			entityContentSB.append("import " + it.next() + ";" + NEWLINESTR);
 		}
 		
 		//添加序列化支持
 		entityContentSB.append("import java.io.Serializable;");
 		
 		entityContentSB.append(NEWLINESTR);
 		entityContentSB.append(NEWLINESTR);
 		
 		//添加类注释  --- 省略

 		//添加类声明
 		entityContentSB.append("public class " + ConfigUtil.simpleModelName +" implements Serializable {" + NEWLINESTR);
 		entityContentSB.append(NEWLINESTR);

 		//添加默认的序列化Id
 		entityContentSB.append(INDENTATION_1 + "private static final long serialVersionUID = 1L;" + NEWLINESTR);
 		//添加类属性声明
 		for(int i = 0 ; i < entityPropertyNameArray.length; i ++){
 			entityContentSB.append(INDENTATION_1 + "private " + entityPropertyTypeArray[i].substring(entityPropertyTypeArray[i].lastIndexOf(".") + 1) + " "+ entityPropertyNameArray[i] + ";" + "//" + columnRemarksArray[i] + NEWLINESTR);
 		}
 		entityContentSB.append(NEWLINESTR);
 		
 		//添加属性的get set 方法
 		// 属性的类型  属性首字母大写
 		String attr_type,attrFirstCharToUpper,attr_name;
 		for(int i = 0 ; i < entityPropertyNameArray.length; i ++){
 			attr_name = entityPropertyNameArray[i];
 			attr_type = entityPropertyTypeArray[i].substring(entityPropertyTypeArray[i].lastIndexOf(".") + 1);
 			attrFirstCharToUpper =attr_name.substring(0, 1).toUpperCase() + attr_name.substring(1);
 			//添加get方法
 			entityContentSB.append(INDENTATION_1 + "public " + attr_type  + " get" + attrFirstCharToUpper + "() {" +  NEWLINESTR);
 			entityContentSB.append(INDENTATION_2 + "return " + attr_name  + ";" +  NEWLINESTR);
 			entityContentSB.append(INDENTATION_1 + "}" +  NEWLINESTR);
 			entityContentSB.append(NEWLINESTR);
 			//添加set方法
 			entityContentSB.append(INDENTATION_1 + "public void set" + attrFirstCharToUpper + "("+attr_type + " " + attr_name +") {" +  NEWLINESTR);
 			entityContentSB.append(INDENTATION_2 + "this." + attr_name  + " = " + attr_name +";" +  NEWLINESTR);
 			entityContentSB.append(INDENTATION_1 + "}" +  NEWLINESTR);
 			entityContentSB.append(NEWLINESTR);
 		}
 		
 		//添加java文件结束
 		entityContentSB.append("}");
 		writeEntityContentToEntityFile();
 	}
 	/**
 	 * 初始化静态数据：将数据库表字段属性 全部初始化到静态变量里边
 	 * @param colRet 列一部分属性集合
 	 * @param rsMeta 列另一部分属性集合
 	 * @throws Exception 
 	 */
 	private static void initStaticData(ResultSet colRet, ResultSetMetaData rsMeta) throws Exception {
 		int columnCount = rsMeta.getColumnCount();
 		columnArray = new String[columnCount];// 列名数组
		entityPropertyNameArray = new String[columnCount];//实体类的属性名称数组
		columnDefaultValueArray = new String[columnCount];//实体类名称默认值数组
		columnTypeArray = new String[columnCount];//列类型数组
		entityPropertyTypeArray = new String[columnCount];//实体类的属性类型数组
		columnDatasizeArray = new int[columnCount];//列的大小数组
		columnDigitsArray = new int[columnCount];//列的精度数组
		columnNullableArray =  new int[columnCount];//列是否为空 数组  0 不能为空 1 可以为空
		columnAutoIncrementArray = new String[columnCount];//列是否自增 数组  是否自增 YES自增 NO非自增
		columnRemarksArray = new String[columnCount];//列的注释 数组
		for (int i = 1; i <= columnCount; i++) {
			// 对应数据类型的类
			String columnClassName = rsMeta.getColumnClassName(i);
			//日期类型需要手动转换一下
			if("java.sql.Timestamp".equals(columnClassName)){
				entityPropertyTypeArray[i - 1] = "java.util.Date";
				continue;
			}else if("java.math.BigInteger".equals(columnClassName)){
				entityPropertyTypeArray[i - 1] = "java.lang.Long";
				continue;
			}
			//System.out.println("获得列" + i + "对应数据类型的类:" + columnClassName);
			entityPropertyTypeArray[i - 1] = columnClassName;
		}
		String columnName,columnType,autoIncrement,remarks,columnDefault; 
		int datasize,digits,nullable;
		int arrayIndex = 0;
		while(colRet.next()) { 
			// 列属性的顺序为 ： 列名 -- 列类型(列大小,列精度) -- 是否为空 -- 是否自增 -- 注释 -- 默认值
			columnName = colRet.getString("COLUMN_NAME"); //列名称 
			columnType = colRet.getString("TYPE_NAME"); // 数据库列类型名称
			datasize = colRet.getInt("COLUMN_SIZE"); //列的大小
			digits = colRet.getInt("DECIMAL_DIGITS"); //小数部分的位数即数据精度
			nullable = colRet.getInt("NULLABLE"); // 是否为空 0 不能为空 1 可以为空
			autoIncrement = colRet.getString("IS_AUTOINCREMENT"); // 是否自增 YES自增 NO非自增
			remarks = colRet.getString("REMARKS"); //列的注释
			columnDefault = colRet.getString("COLUMN_DEF"); // 获取列的默认值
			columnArray[arrayIndex] = columnName.toLowerCase();
			entityPropertyNameArray[arrayIndex] = getColumnInEntityName(columnName);
			columnDefaultValueArray[arrayIndex] = MysqlUtil.getColumnInsertDefaultStr(columnType, columnDefault);
			if(columnType.equals("INT UNSIGNED") || columnType.equals("BIGINT UNSIGNED")){
				columnTypeArray[arrayIndex] = "BIGINT";
			}else{
				columnTypeArray[arrayIndex] = columnType;
			}
			columnDatasizeArray[arrayIndex] = datasize;
			columnDigitsArray[arrayIndex] = digits;
			columnNullableArray[arrayIndex] = nullable;
			columnAutoIncrementArray[arrayIndex] = autoIncrement;
			columnRemarksArray[arrayIndex] = remarks;
			arrayIndex++;
		}
	}
 	/**
	 * 将entity内容 写入java文件
	 */
	public static void writeEntityContentToEntityFile(){
		FileWriter fw = null;
		try {
			String filePath = "source/" + ConfigUtil.simpleModelNameLower + "/entity/" + ConfigUtil.simpleModelName  + ".java";
			File mapperFile = new File(filePath);
			if(!mapperFile.exists()){
				mapperFile.createNewFile();
			}
			fw = new FileWriter(mapperFile);
			fw.write(entityContentSB.toString());
			System.out.println(ConfigUtil.simpleModelName + ".java写入成功！文件存放路径为：" + filePath);
		} catch (IOException e) {
			System.out.println(ConfigUtil.simpleModelName + ".java写入失败！");
		}finally {
			try {
				fw.close();
			} catch (IOException e) {
				System.out.println("写入java文件的写入流关闭是失败！");
			}
		}
	}
}
